package com.mzj.saas.jobs.lock.service.xizhao;

import com.alibaba.fastjson.JSON;
import com.mzj.saas.commons.enums.BacklogItemTypeEnum;
import com.mzj.saas.commons.enums.LockAlarmTypeEnum;
import com.mzj.saas.jobs.backlog.entity.BacklogItem;
import com.mzj.saas.jobs.backlog.entity.BacklogItemLockOff;
import com.mzj.saas.jobs.backlog.entity.SmartLock;
import com.mzj.saas.jobs.backlog.repository.BacklogItemLockOffRepository;
import com.mzj.saas.jobs.backlog.repository.BacklogItemRepository;
import com.mzj.saas.jobs.backlog.repository.SmartLockRepository;
import com.mzj.saas.jobs.bill.entity.*;
import com.mzj.saas.jobs.bill.repository.*;
import com.mzj.saas.jobs.commons.DateUtils;
import com.mzj.saas.jobs.lock.entity.BacklogItemBattery;
import com.mzj.saas.jobs.lock.entity.LockAlarm;
import com.mzj.saas.jobs.lock.entity.LockHouseSetting;
import com.mzj.saas.jobs.lock.entity.LockOpenLog;
import com.mzj.saas.jobs.lock.repository.BacklogItemBatteryRepository;
import com.mzj.saas.jobs.lock.repository.LockAlarmRepository;
import com.mzj.saas.jobs.lock.repository.LockHouseSettingRepository;
import com.mzj.saas.jobs.lock.repository.LockOpenLogRepository;
import com.mzj.saas.jobs.lock.vo.SmartLockCallBackVO;
import com.mzj.saas.jobs.lock.vo.yaluete.SmartLockVO;
import com.mzj.saas.jobs.redis.RedisService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 熙照-智能锁事件处理
 *
 * @author hp
 */
@Service
public class SmarkLockXzEventHandleService {

    private static final Logger log = LoggerFactory.getLogger(SmarkLockXzEventHandleService.class);

    private static final String authSql = "SELECT a.id AS lockAuthId,a.author_user_id as userId,a.user_name as userName  FROM saas_smart_lock_auth a "
            + "LEFT  JOIN  saas_smart_lock_pwd p ON a.id = p.lock_auth_id \n"
            + "WHERE  a.lock_id = ? AND p.pwd_index_num  = ?";

    private static final String cardSql = "SELECT a.id AS lockAuthId,a.author_user_id as userId,a.user_name AS userName FROM saas_smart_lock_auth a LEFT JOIN "
            + "saas_smart_lock_card c ON a.id = c.lock_auth_id WHERE a.lock_id = ? AND c.card_index_num = ?";

    private static final String fingerprintSql = "SELECT a.id AS lockAuthId,a.author_user_id as userId,a.user_name AS userName FROM saas_smart_lock_auth a LEFT JOIN "
            + "saas_smart_lock_fingerprint f ON a.id = f.lock_auth_id WHERE a.lock_id = ? AND f.fingerprint_index_num = ?";

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private RedisService redisService;
    @Autowired
    private HouseRepository houseRepository;
    @Autowired
    private SmartLockRepository smartLockRepository;
    @Autowired
    private LockOpenLogRepository lockOpenLogRepository;
    @Autowired
    private SmartLockPwdRepository smartLockPwdRepository;
    @Autowired
    private BacklogItemRepository backlogItemRepository;
    @Autowired
    BacklogItemBatteryRepository backlogItemBatteryRepository;
    @Autowired
    private BacklogItemLockOffRepository backlogItemLockOffRepository;
    @Autowired
    private SmartLockFingerprintRepository smartLockFingerprintRepository;
    @Autowired
    private LockAlarmRepository lockAlarmRepository;
    @Autowired
    private SmartLockAuthRepository smartLockAuthRepository;
    @Autowired
    private SmartLockCardRepository smartLockCardRepository;
    @Autowired
    private LockFrozenRepository lockFrozenRepository;
    @Autowired
    private LockHouseSettingRepository lockHouseSettingRepository;
    @Autowired
    private AppUserRepository appUserRepository;
    @Autowired
    private CommunityHouseUserRepository communityHouseUserRepository;

    /**
     * 锁离线事件
     */
    public void lockOfflineCallBack(SmartLockCallBackVO vo) {
        log.info("智能锁事件推送处理-->锁离线事件 vo={}", JSON.toJSONString(vo));
        try {
            SmartLock smartLock = smartLockRepository.findBySn(vo.getDeviceId());
            if (smartLock == null) {
                log.warn("智能锁事件推送处理-->锁离线事件, 数据库未找到设备信息, deviceId={}", vo.getDeviceId());
                return;
            }
            smartLock.setOnlineStatus(0);
            smartLockRepository.save(smartLock);

            Date date = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String today = formatter.format(date);

            BacklogItem log = backlogItemRepository.findByHouseIdAndType(smartLock.getHouseId(),
                    BacklogItemTypeEnum.LOCK_UNLINE.getValue(), today);

            if (log != null) {
                return;
            }

            String content = smartLock.getCommunityName() + smartLock.getUnitName() + smartLock.getBuildName()
                    + smartLock.getRoomNumber();
            // 代办事项
            BacklogItem item = new BacklogItem();
            item.setHouseId(smartLock.getHouseId());
            item.setOrgId(smartLock.getOrgId());
            item.setTitle("门锁离线告警");
            item.setContent(content);
            item.setBusinessStatus("门锁离线量告警");
            item.setType(BacklogItemTypeEnum.LOCK_UNLINE.getValue());
            item.setHandleStatus(0);
            item.setMatchUserId(smartLock.getMatchUserId());
            if (StringUtils.isNotEmpty(smartLock.getMatchUserId())) {
                AppUser appUsers = appUserRepository.findByIdOrEnterpriseUserId(smartLock.getMatchUserId(), smartLock.getMatchUserId());
                if (appUsers != null) {
                    item.setPhone(appUsers.getPhone());
                }

            } else {
                List<CommunityHouseUser> communityHouseUserList = communityHouseUserRepository.findByCommunityHouseIdAndStatusAndType(smartLock.getHouseId(), 1, 1);
                if (communityHouseUserList != null && communityHouseUserList.size() > 0) {
                    item.setMatchUserId(communityHouseUserList.get(0).getUserId()); //承租人ID
                    item.setPhone(communityHouseUserList.get(0).getMobile());//电话
                }
            }
            item.setCreateTime(date);
            backlogItemRepository.save(item);

            // 门锁离线-待办事项参数数据
            BacklogItemLockOff lockoff = new BacklogItemLockOff();
            lockoff.setBacklogItemId(item.getId());
            lockoff.setLockId(smartLock.getId());
            lockoff.setMatchUserId(smartLock.getMatchUserId());
            backlogItemLockOffRepository.save(lockoff);

        } catch (Exception e) {
            log.error("锁离线事件处理异常" + e.getMessage(), e);
        }
    }

    /**
     * 锁在线事件
     */
    public void lockOnlineCallBack(SmartLockCallBackVO vo) {
        log.info("智能锁事件推送处理-->锁在线事件 vo={}", JSON.toJSONString(vo));
        try {
            SmartLock smartLock = smartLockRepository.findBySn(vo.getDeviceId());
            if (smartLock == null) {
                log.warn("智能锁事件推送处理-->锁在线事件, 数据库未找到设备信息, deviceId={}", vo.getDeviceId());
                return;
            }
            smartLock.setOnlineStatus(1);
            smartLockRepository.save(smartLock);
        } catch (Exception e) {
            log.error("锁在线事件处理异常" + e.getMessage(), e);
        }
    }

    /**
     * 锁注册/入网
     */
    public void addParkCallBack(SmartLockCallBackVO vo) {
        log.info("智能锁事件推送处理-->锁注册事件 vo={}", JSON.toJSONString(vo));
        try {
            SmartLock smartLock = smartLockRepository.findByMac(vo.getGatewayId());
            if (smartLock == null) {
                log.warn("智能锁事件推送处理-->锁注册事件, 数据库未找到设备信息, deviceId={}", vo.getDeviceId());
                return;
            }
            smartLock.setSn(vo.getDeviceId());
            // 在线状态
            smartLock.setOnlineStatus(1);
            // 激活状态
            smartLock.setMechineStatus(1);
            smartLockRepository.save(smartLock);
        } catch (Exception e) {
            log.error("锁在线事件处理异常" + e.getMessage(), e);
        }
    }

    /**
     * 锁开门事件
     *
     * @param vo
     */
    public void openRecordCallBack(SmartLockCallBackVO vo) {
        log.info("智能锁事件推送处理-->锁开门事件 vo={}", JSON.toJSONString(vo));
        try {

            SmartLock lock = smartLockRepository.findBySn(vo.getDeviceId());
            if (lock == null) {
                log.warn("智能锁事件推送处理-->锁离线事件, 数据库未找到设备信息, deviceId={}", vo.getDeviceId());
                return;
            }
            SmartLockPwd pwd = smartLockPwdRepository.findByLockIdAndPwdIndexNum(lock.getId(), vo.getIndex());
            // 开门类型（0：普通密码；1：动态密码；5：次数密码；9：管理员密码；10：一键开门； 11：普通卡；21：指纹）
            Integer passType = getLockPwdType(vo.getType(), vo.getIndex());
            if (passType == null && pwd != null && pwd.getAuthType() == 3) {
                // 次数密码
                passType = 3;
            }

            if (passType == null) {
                passType = 0;
            }

            // 开门记录
            LockOpenLog log = new LockOpenLog();
            log.setLockId(lock.getId());
            log.setHouseId(lock.getHouseId());
            log.setOpenMode(passType);
            log.setOpenType(1);// 开门类型：0未知 1外开门 2内开门
            log.setBuildName(lock.getBuildName());
            log.setCommunityName(lock.getCommunityName());
            log.setUnitName(lock.getUnitName());
            log.setMatchUserName(lock.getMatchUserName());
            log.setRoomNumber(lock.getRoomNumber());
            log.setOpenTime(DateUtils.stringToDateTimeForTags(vo.getTime(), DateUtils.FORMAT_DATETIME_14));
            log.setUserProperty(0);// 开门人性质：0未知 1承租人 2同住人

            // 次数密码,减去

            // 密码设置方式：1永久 2时间期限 3次数
            if (pwd != null && pwd.getAuthType() == 3) {
                Integer times = pwd.getTimes() <= 0 ? 0 : pwd.getTimes() - 1;
                pwd.setTimes(times);
                smartLockPwdRepository.save(pwd);
            } else {
                // 检测是否为临时密码, 临时密码索引默认且固定为50
				/*String key = vo.getDeviceId() + "_pwd_50";

				SmartLockVO lockVo = redisService.getLockCallBack(key);
				if (lockVo != null) {
					LockHouseSetting lockHouseSetting = lockHouseSettingRepository.findByLockId(lock.getId());
					if(lockHouseSetting.getTimes() != null){
						Integer times = lockHouseSetting.getTimes() <= 0 ? 0 : lockHouseSetting.getTimes() - 1;
						lockHouseSetting.setTimes(times);
						lockHouseSettingRepository.save(lockHouseSetting);
					}
				}*/
            }

            // 0普通密码 5次数密码
            if (passType == 0 || passType == 5) {
                smartLockPwd(log, vo.getIndex(), vo.getDeviceId(), lock.getMatchUserId());
            } else if (passType == 1) { // 1动态密码
            } else if (passType == 11) { // 11普通卡
                smartLockCard(log, vo.getIndex(), vo.getDeviceId(), lock.getMatchUserId());
            } else if (passType == 21) { // 21指纹
                smartLockFingerprint(log, vo.getIndex(), vo.getDeviceId(), lock.getMatchUserId());
            }

            lockOpenLogRepository.save(log);
        } catch (Exception e) {
            log.error("锁开门事件处理异常" + e.getMessage(), e);
        }
    }

    /**
     * 密码开门记录
     */
    private void smartLockPwd(LockOpenLog lock, Integer pwdIndexNum, String sn, String matchUserId) {

        List<Map<String, Object>> lockAuthList = jdbcTemplate.queryForList(authSql, lock.getLockId(), pwdIndexNum);

        if (CollectionUtils.isEmpty(lockAuthList)) {
            log.warn("智能锁事件推送处理-->密码锁开门事件,未找到相关开门人信息 sn={},lockId={},pwdIndexNum={}", sn, lock.getLockId(),
                    pwdIndexNum);
            return;
        }
        Map<String, Object> authMap = lockAuthList.get(0);
        Long lockAuthId = Long.parseLong(authMap.get("lockAuthId").toString());
        String userId = authMap.get("userId").toString();
        if (matchUserId.equals(userId)) {
            lock.setUserProperty(1);
        } else {
            lock.setUserProperty(2);
        }
        String userName = authMap.get("userName").toString();
        lock.setLockAuditId(lockAuthId);
        lock.setOpenUserName(userName);
    }

    /**
     * 指纹开门记录
     */
    private void smartLockFingerprint(LockOpenLog lock, Integer fingerprintIndexNum, String sn, String matchUserId) {
        List<Map<String, Object>> lockAuthList = jdbcTemplate.queryForList(fingerprintSql, lock.getLockId(),
                fingerprintIndexNum);
        if (CollectionUtils.isEmpty(lockAuthList)) {
            log.warn("智能锁事件推送处理-->指纹开门事件,未找到相关开门人信息 sn={}, lockId={}, fingerprintIndexNum={}", sn, lock.getLockId(),
                    fingerprintIndexNum);
            return;
        }
        Map<String, Object> authMap = lockAuthList.get(0);
        Long lockAuthId = Long.parseLong(authMap.get("lockAuthId").toString());
        String userId = authMap.get("userId").toString();
        if (matchUserId.equals(userId)) {
            lock.setUserProperty(1);
        } else {
            lock.setUserProperty(2);
        }
        String userName = authMap.get("userName").toString();
        lock.setLockAuditId(lockAuthId);
        lock.setOpenUserName(userName);
    }

    /**
     * 卡开门记录
     */
    public void smartLockCard(LockOpenLog lock, Integer pwdIndexNum, String sn, String matchUserId) {

        List<Map<String, Object>> lockAuthList = jdbcTemplate.queryForList(cardSql, lock.getLockId(), pwdIndexNum);
        if (CollectionUtils.isEmpty(lockAuthList)) {
            log.warn("智能锁事件推送处理-->卡开门事件,未找到相关开门人信息 sn={}, lockId={}, pwdIndexNum={}", sn, lock.getLockId(),
                    pwdIndexNum);
            return;
        }
        Map<String, Object> authMap = lockAuthList.get(0);
        Long lockAuthId = Long.parseLong(authMap.get("lockAuthId").toString());
        String userId = authMap.get("userId").toString();
        if (matchUserId.equals(userId)) {
            lock.setUserProperty(1);
        } else {
            lock.setUserProperty(2);
        }
        String userName = authMap.get("userName").toString();
        lock.setLockAuditId(lockAuthId);
        lock.setOpenUserName(userName);
    }

    /**
     * 锁低电量事件
     *
     * @param vo
     */
    public void lowBatteryCallBack(SmartLockCallBackVO vo) {
        log.info("智能锁事件推送处理-->锁低电量事件 vo={}", JSON.toJSONString(vo));
        try {

            SmartLock lock = smartLockRepository.findBySn(vo.getDeviceId());
            if (lock == null) {
                log.warn("智能锁事件推送处理-->锁低电量事件, 数据库未找到设备信息, deviceId={}", vo.getDeviceId());
                return;
            }
            // 如果锁入网事件没有正常推送，SN为空时，接收到低电量事件时
            if (StringUtils.isEmpty(lock.getSn()) && StringUtils.isNotEmpty(vo.getDeviceId())) {
                lock.setSn(vo.getDeviceId());
                // 在线状态
                lock.setOnlineStatus(1);
                // 激活状态
                lock.setMechineStatus(1);
            }
            lock.setElectricQuantity(Integer.parseInt(vo.getPower()));
            smartLockRepository.save(lock);

            Date date = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String today = formatter.format(date);

            // 查询是否低电量告警
            LockHouseSetting lockHouseSetting = lockHouseSettingRepository.findByLockId(lock.getId());
            // 已开启告警，并当前设备电量小于告警电量时，处理低电量告警
            if (lockHouseSetting == null || lockHouseSetting.getLowPowerStatus() == null
                    || lockHouseSetting.getLowPowerStatus() == 0 || lockHouseSetting.getLowPowerValue() == null
                    || lockHouseSetting.getLowPowerValue() == 0
                    || lock.getElectricQuantity() > lockHouseSetting.getLowPowerValue()) {
                log.warn("智能锁事件推送处理-->锁低电量事件, 不符合低电量告警要求, deviceId={}", vo.getDeviceId());
                return;
            }

            // 查询待办事项，当前是否有产生，如果有不重复记录
            BacklogItem log = backlogItemRepository.findByHouseIdAndType(lock.getHouseId(),
                    BacklogItemTypeEnum.LOCK_LOW_BATTERY.getValue(), today);

            if (log != null) {
                return;
            }

            String content = lock.getCommunityName() + lock.getUnitName() + lock.getBuildName() + lock.getRoomNumber();
            // 待办事项
            BacklogItem item = new BacklogItem();
            item.setHouseId(lock.getHouseId());
            item.setOrgId(lock.getOrgId());
            item.setTitle("门锁低电量告警");
            item.setContent(content);
            item.setBusinessStatus("门锁低电量告警");
            item.setType(BacklogItemTypeEnum.LOCK_LOW_BATTERY.getValue());
            item.setHandleStatus(0);
            item.setMatchUserId(lock.getMatchUserId());
            if (StringUtils.isNotEmpty(lock.getMatchUserId())) {
                AppUser appUsers = appUserRepository.findByIdOrEnterpriseUserId(lock.getMatchUserId(), lock.getMatchUserId());
                if (appUsers != null) {
                    item.setPhone(appUsers.getPhone());
                }

            } else {
                List<CommunityHouseUser> communityHouseUserList = communityHouseUserRepository.findByCommunityHouseIdAndStatusAndType(lock.getHouseId(), 1, 1);
                if (communityHouseUserList != null && communityHouseUserList.size() > 0) {
                    item.setMatchUserId(communityHouseUserList.get(0).getUserId()); //承租人ID
                    item.setPhone(communityHouseUserList.get(0).getMobile());//电话
                }
            }

            item.setCreateTime(date);
            backlogItemRepository.save(item);
            // 门锁低电量待办事项告警
            BacklogItemBattery battery = new BacklogItemBattery();
            battery.setBacklogItemId(item.getId());
            battery.setLockId(lock.getId());
            battery.setMatchUserId(lock.getMatchUserId());
            backlogItemBatteryRepository.save(battery);

            // 低电量告警记录
            LockAlarm lockAlarm = new LockAlarm();
            lockAlarm.setAlarmTime(date);
            lockAlarm.setAlarmType(LockAlarmTypeEnum.LOW.getValue());
            lockAlarm.setElectric(lock.getElectricQuantity());
            lockAlarm.setLockId(lock.getId());
            lockAlarm.setSn(lock.getSn());
            lockAlarm.setHouseId(lock.getHouseId());
            lockAlarmRepository.save(lockAlarm);

        } catch (Exception e) {
            log.error("锁低电量事件处理异常" + e.getMessage(), e);
        }
    }

    /**
     * 门锁密码改变回调
     *
     * @param vo
     */
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public void clearPwdCallBack(SmartLockCallBackVO vo) {
        log.info("智能锁事件推送处理-->门锁密码改变回调 vo={}", JSON.toJSONString(vo));
        try {
            String key = vo.getDeviceId() + "_pwd_" + vo.getPwdSeq();
            if ("change".equals(vo.getType())) {
                if ("card".equals(vo.getPasswordtype())) {
                    key = vo.getDeviceId() + "_card_" + vo.getPwdSeq();
                } else if ("fingerprint".equals(vo.getPasswordtype())) {
                    key = vo.getDeviceId() + "_fingerprint_" + vo.getPwdSeq();
                }
            } else {
                key = vo.getDeviceId() + "_del_" + vo.getIndex();
            }

            SmartLockVO lockVo = redisService.getLockCallBack(key);
            if (lockVo == null) {
                log.warn("修改或删除密码回调, 请求非法  sn={}, index={}", vo.getDeviceId(), vo.getIndex());
                return;
            }
            // 临时密码不处理用户授权业务
            if (lockVo.getPasswordType() != null && lockVo.getPasswordType() == 2) {
                log.info("临时密码回调 sn={}", lockVo.getSn());
                // 更新锁设置表状态
                lockHouseSettingRepository.updatePwdStatus(1, vo.getIndex(), lockVo.getSn());
            } else {
                // 智能锁用户授权明细
                SmartLockAuth auth = smartLockAuthRepository.findSmartLockAuthById(lockVo.getAuthInfoId());

                if (auth == null) {
                    log.warn("智能锁事件推送处理-->未找到智能锁用户授权明细   sn={}, type={}, pwdSeq={}, authInfoId={}", vo.getDeviceId(),
                            vo.getType(), vo.getPwdSeq(), lockVo.getAuthInfoId());
                    return;
                }

                // change/del
                if ("change".equals(vo.getType())) {
                    log.info("智能锁事件推送处理-->门锁授权改变, deviceId={}, passwordtype={}", vo.getDeviceId(),
                            vo.getPasswordtype());

                    if ("code".equals(vo.getPasswordtype())) {
                        // 更新授权状态
                        auth.setPwdStatus(1);

                        // 密码授权-授权类型明细
                        SmartLockPwd lockPwd = smartLockPwdRepository.findByLockAuthId(auth.getId());

                        if (lockPwd == null) {
                            log.warn("智能锁事件推送处理-->未找到密码授权-授权类型明细 sn={}, type={}, pwdSeq={}, authInfoId={}",
                                    vo.getDeviceId(), vo.getType(), vo.getPwdSeq(), lockVo.getAuthInfoId());
                            return;
                        }
                        // 更新密码授权-授权类型明细
                        lockPwd.setStatus(1);
                        lockPwd.setPwdIndexNum(vo.getIndex());
                        lockPwd.setLastUpdateTime(new Date());
                        smartLockPwdRepository.save(lockPwd);
                    } else if ("card".equals(vo.getPasswordtype())) {
                        // 更新授权状态
                        auth.setCardStatus(1);

                        // 更新卡数据
                        SmartLockCard card = smartLockCardRepository.findByLockAuthIdAndTypeAndCardIndex(auth.getId(),
                                lockVo.getCardType(), Integer.parseInt(vo.getPwdSeq()));

                        if (card == null) {
                            log.warn("智能锁事件推送处理-->未找到卡授权-授权类型明细 sn={}, type={}, pwdSeq={}, authInfoId={}",
                                    vo.getDeviceId(), vo.getType(), vo.getPwdSeq(), lockVo.getAuthInfoId());
                            return;
                        }
                        card.setStatus(1);
                        card.setCardIndexNum(vo.getIndex());
                        card.setLastUpdateTime(new Date());
                        smartLockCardRepository.save(card);
                    } else if ("fingerprint".equals(vo.getPasswordtype())) {
                        // 更新授权状态
                        auth.setFingerprintStatus(1);

                        // 查询指纹信息
                        SmartLockFingerprint fingerprint = smartLockFingerprintRepository
                                .findByLockAuthIdAndFingerprintIndex(lockVo.getAuthInfoId(),
                                        Integer.parseInt(vo.getPwdSeq()));

                        if (fingerprint == null) {
                            log.warn("智能锁事件推送处理-->未找到指纹授权-授权类型明细 sn={}, type={}, pwdSeq={}, authInfoId={}",
                                    vo.getDeviceId(), vo.getType(), vo.getPwdSeq(), lockVo.getAuthInfoId());
                            return;
                        }
                        fingerprint.setStatus(1);
                        fingerprint.setFingerprintIndexNum(vo.getIndex());
                        fingerprint.setLastUpdateTime(new Date());
                        smartLockFingerprintRepository.save(fingerprint);
                    }
                    smartLockAuthRepository.save(auth);
                } else if ("del".equals(vo.getType())) {
                    log.info("智能锁事件推送处理-->门锁授权删除, deviceId={}, passwordtype={}", vo.getDeviceId(),
                            vo.getPasswordtype());
                    if ("code".equals(vo.getPasswordtype())) {
                        // 删除密码
                        SmartLockPwd lockPwd = smartLockPwdRepository.findByLockIdAndPwdIndexNum(auth.getId(),
                                vo.getIndex());

                        if (lockPwd != null) {
                            log.warn("智能锁事件推送处理-->未找到密码授权-授权类型明细 sn={}, type={}, pwdSeq={}, authInfoId={}",
                                    vo.getDeviceId(), vo.getType(), vo.getPwdSeq(), lockVo.getAuthInfoId());
                            // 删除授权明细记录
                            smartLockPwdRepository.delete(lockPwd);
                        }

                        // 更新密码授权状态为：未授权
                        auth.setPwdStatus(0);
                        smartLockAuthRepository.save(auth);
                    } else if ("card".equals(vo.getPasswordtype())) {
                        // 删除卡
                        SmartLockCard card = smartLockCardRepository.findByLockAuthIdAndTypeAndCardIndexNum(
                                lockVo.getAuthInfoId(), lockVo.getCardType(), vo.getIndex());
                        if (card != null) {
                            smartLockCardRepository.delete(card);
                        }

                        Integer count = smartLockCardRepository.countByLockAuthId(lockVo.getAuthInfoId());
                        if (count == null || count == 0) {
                            auth.setCardStatus(0);
                            smartLockAuthRepository.save(auth);
                        }
                    } else if ("fingerprint".equals(vo.getPasswordtype())) {
                        // 删除指纹
                        SmartLockFingerprint fingerprint = smartLockFingerprintRepository
                                .findByLockAuthIdAndFingerprintIndexNum(lockVo.getAuthInfoId(), vo.getIndex());
                        if (fingerprint != null) {
                            smartLockFingerprintRepository.delete(fingerprint);
                        }

                        auth.setFingerprintStatus(0);
                        smartLockAuthRepository.save(auth);
                    }
                }
            }

            redisService.delLockClassBack(vo.getDeviceId() + "_pwd_" + vo.getPwdSeq(), lockVo);
        } catch (Exception e) {
            log.error("门锁密码改变回调异常" + e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 冻结或解冻回调
     *
     * @param vo
     */
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public void freezeOrUnfreezeCardCallBack(SmartLockCallBackVO vo) {
        log.info("智能锁事件推送处理-->冻结或解冻卡回调 vo={}", JSON.toJSONString(vo));
        try {
            SmartLockVO lockVo = redisService.getLockCallBack(vo.getDeviceId() + "_freeze_" + vo.getIndex());
            if (lockVo == null) {
                log.warn("冻结或解冻卡回调, 请求非法  sn={}, index={}", vo.getDeviceId(), vo.getIndex());
                return;
            }

            log.info("冻结或解冻卡回调, REDIS缓存数据, lockVo={}", JSON.toJSONString(lockVo));

            // 智能锁用户授权明细
            SmartLockAuth auth = smartLockAuthRepository.findSmartLockAuthById(lockVo.getAuthInfoId());

            Optional<SmartLock> smartLockOptional = smartLockRepository.findById(auth.getLockId());
            if (!smartLockOptional.isPresent()) {
                log.info("冻结或解冻卡回调 智能锁不存在 sn={}", lockVo.getSn());
                return;
            }
            SmartLock smartLock = smartLockOptional.get();

            // "FREEZE/ACTIVE" 冻结、解冻状态：冻结/解冻
            if (StringUtils.isNotEmpty(vo.getStatus()) && "FREEZE".equals(vo.getStatus())) {
                // 更新智能锁冻结记录
                Optional<LockFrozen> frozenOpt = lockFrozenRepository.findById(lockVo.getLockFrozenId());
                LockFrozen frozen = null;
                if (frozenOpt.isPresent()) {
                    frozen = frozenOpt.get();
                }
                /**
                 * 冻结处理
                 */
                // 密码冻结
                if ("code".equals(vo.getType())) {
                    auth.setPwdStatus(2);
                    if (frozen != null) {
                        frozen.setPwdStatus(1);
                    }
                    // 执行状态更新
                    SmartLockPwd lockPwd = smartLockPwdRepository.findByLockAuthId(lockVo.getAuthInfoId());
                    lockPwd.setStatus(1);
                    smartLockPwdRepository.save(lockPwd);
                } else if ("card".equals(vo.getType())) {
                    // 判断是身份证/CPU卡 1身份证 2CPU卡
                    if (lockVo.getCardType() != null && lockVo.getCardType() == 1) {
                        auth.setCardStatus(2);
                        if (frozen != null) {
                            frozen.setPwdStatus(1);
                        }
                    } else if (lockVo.getCardType() != null && lockVo.getCardType() == 2) {
                        auth.setCpuStatus(2);
                        if (frozen != null) {
                            frozen.setCpuStatus(1);
                        }
                    } else {
                        log.info("冻结卡回调, 卡类型识别失败, lockVo={}", JSON.toJSONString(lockVo));
                    }

                    // 执行状态更新
                    SmartLockCard lockCard = smartLockCardRepository.findByLockAuthIdAndType(lockVo.getAuthInfoId(),
                            lockVo.getCardType());
                    lockCard.setStatus(1);
                    smartLockCardRepository.save(lockCard);
                } else if ("fingerprint".equals(vo.getType())) {
                    // 指纹冻结
                    auth.setFingerprintStatus(2);
                    if (frozen != null) {
                        frozen.setFingerprintStatus(1);
                    }

                    // 执行状态更新
                    SmartLockFingerprint lockFingerprint = smartLockFingerprintRepository
                            .findByLockAuthIdAndFingerprintIndexNum(lockVo.getAuthInfoId(), vo.getIndex());
                    lockFingerprint.setStatus(1);
                    smartLockFingerprintRepository.save(lockFingerprint);
                }
                smartLockAuthRepository.save(auth);

                if (frozen != null) {
                    lockFrozenRepository.save(frozen);
                }

                //验证是否已全部冻结，如果已全部冻结，更新智能锁状态为：已冻结
                if (lockVo.getSuspend() == 1) {
                    if (smartLock.getBindType() == 1) {
                        int authCount = smartLockAuthRepository.findSmartLockAuthByLockId(auth.getLockId());
                        List<SmartLockAuth> auths = smartLockAuthRepository.findByLockIdAndBindType(auth.getLockId(), 0);
                        if (authCount == auths.size()) {
                            smartLock.setMechineStatus(2);
                            smartLockRepository.save(smartLock);

                            // 全部冻结时, 更新公租房锁授权状态
                            String houseId = smartLock.getHouseId();
                            houseRepository.updateLockStatusById(houseId, 4);
                        }
                    } else {
                        int authCount = smartLockAuthRepository.findPersonSmartLockAuthByLockId(auth.getLockId());
                        List<SmartLockAuth> auths = smartLockAuthRepository.findByLockIdAndBindType(auth.getLockId(), 1);
                        if (authCount == auths.size()) {
                            smartLock.setMechineStatus(2);
                            smartLockRepository.save(smartLock);

                            // 全部冻结时, 更新公租房锁授权状态
                            String houseId = smartLock.getHouseId();
                            houseRepository.updateLockStatusById(houseId, 4);
                        }
                    }
                }
            } else if (StringUtils.isNotEmpty(vo.getStatus()) && "ACTIVE".equals(vo.getStatus())) {
                /**
                 * 解冻处理
                 */
                // 密码解冻
                if ("code".equals(vo.getType())) {
                    auth.setPwdStatus(1);
                    // 执行状态更新
                    SmartLockPwd lockPwd = smartLockPwdRepository.findByLockAuthId(lockVo.getAuthInfoId());
                    lockPwd.setStatus(1);
                    smartLockPwdRepository.save(lockPwd);
                } else if ("card".equals(vo.getType())) {
                    // 判断是身份证/CPU卡 1身份证 2CPU卡
                    if (lockVo.getCardType() != null && lockVo.getCardType() == 1) {
                        auth.setCardStatus(1);
                    } else if (lockVo.getCardType() != null && lockVo.getCardType() == 2) {
                        auth.setCpuStatus(1);
                    } else {
                        log.info("解冻卡回调, 卡类型识别失败, lockVo={}", JSON.toJSONString(lockVo));
                    }

                    // 执行状态更新
                    SmartLockCard lockCard = smartLockCardRepository.findByLockAuthIdAndType(lockVo.getAuthInfoId(),
                            lockVo.getCardType());
                    lockCard.setStatus(1);
                    smartLockCardRepository.save(lockCard);
                } else if ("fingerprint".equals(vo.getType())) {
                    // 指纹解冻
                    auth.setFingerprintStatus(1);

                    // 执行状态更新
                    SmartLockFingerprint lockFingerprint = smartLockFingerprintRepository
                            .findByLockAuthIdAndFingerprintIndexNum(lockVo.getAuthInfoId(), vo.getIndex());
                    lockFingerprint.setStatus(1);
                    smartLockFingerprintRepository.save(lockFingerprint);
                }

                // 只要智能锁有一个解冻，锁状态修改为解冻状态
                if (lockVo.getSuspend() == 0) {
                    smartLock.setMechineStatus(1);
                    smartLockRepository.save(smartLock);

                    // 任意授权解冻时, 更新公租房锁授权状态
                    String houseId = smartLock.getHouseId();
                    houseRepository.updateLockStatusById(houseId, 1);
                }
            }

            if (lockVo.getSuspend() == 1) {
                // 更新智能锁冻结记录
                Optional<LockFrozen> frozenOpt = lockFrozenRepository.findById(lockVo.getLockFrozenId());

                if (frozenOpt.isPresent()) {
                    LockFrozen frozen = frozenOpt.get();
                    frozen.setCardStatus(1);
                    lockFrozenRepository.save(frozen);
                }
            }

            smartLockAuthRepository.save(auth);
            redisService.delLockClassBack(vo.getDeviceId() + "_freeze_" + vo.getIndex(), lockVo);
        } catch (Exception e) {
            log.error("冻结或解冻密码回调异常" + e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 获取开门方式
     *
     * @param type
     * @return
     * @author shun
     * @date 2021年7月1日
     */
    public Integer getLockPwdType(String type, Integer index) {
        // 密码编号 1001-2000 为普通密码/65520 为动态密码/0 为管理员密码
        if (index != null && index == 65520) {
            // 为动态密码
            return 1;
        }

        if (index == 0) {
            // 管理员密码
            return 9;
        }

        // 0普通密码 1动态密码 5次数密码 9管理员密码 10一键开门 11普通卡 21指纹
        switch (type) {
            case "adminpwd":
                return 9;
            case "code":
                return 0;
            case "card":
                return 11;
            case "fingerprint":
                return 21;
            default:

        }

        return null;
    }
}
